<?php
/*
 * Copyright (c) 2009 Tom Smith (tom@takeontom.com).
 * 
 * Distributed under the terms of the GNU Lesser General Public License.
 * 
 * ---------------------------------------------------------------------------------
 * 
 * This file is part of Seraph PHP Framework.
 *
 * Seraph PHP Framework is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Seraph PHP Framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Seraph PHP Framework.  If not, see <http://www.gnu.org/licenses/>.
*/


/**
 * Entry point for Model
 * 
 * @author Tom
 *
 */
class Model	{
	private static $DBs = array();
	private static $defaultDBName;
	
	//cache of entities
	private static $entities;
	
	private static $entityNames = array();
	
	private static $autoloader;
	
	public static function addDatabase($name, DBConnection $db, $default = false)	{
		self::$DBs[$name] = $db;
		if ($default || count(self::$DBs) == 1)	{
			self::setDefaultDatabaseName($name);
		}
	}
	
	/**
	 * Remove all database connections from the model.
	 * 
	 */
	static public function clearDatabaseConnections()	{
		self::$DBs = array();
		self::$defaultDBName = null;
	}
		
	/**
	 * 
	 * @param $name
	 * @return DBConnection
	 */
	public static function getDatabase($name = false)	{
		if (!$name)	{
			return self::getDefaultDatabase();
		}
		
		if (isset(self::$DBs[$name]))	{
			return self::$DBs[$name];
		}
		return false;
	}
	
	/**
	 * Get an array of all the database connections added to the model
	 */
	static public function getDatabases()	{
		return self::$DBs;
	}
	
	/**
	 * Sets the name of the default database connection.
	 * 
	 * Will check whether the specified database actually exists before setting the default.
	 * 
	 * Use this with getDefaultDatabase().
	 * 
	 * @param $databaseName
	 */
	public static function setDefaultDatabaseName($databaseName)	{
		if (isset(self::$DBs[$databaseName]))	{
			self::$defaultDBName = $databaseName;
			return true;
		}
		return false;
	}
	
	/**
	 * Will return the default database.
	 * 
	 * If the default database has not been explicity defined, this will
	 * return the first database added to the model. 
	 * 
	 * @return DBConnection
	 */
	public static function getDefaultDatabase()	{
		if (count(self::$DBs) == 0)	{
			return false;
		}
		
		if (self::$defaultDBName)	{	
			return self::getDatabase(self::$defaultDBName);
		}
		
	}
	
	/**
	 * 
	 * @return IAutoloader
	 */
	public static function getAutoloader()	{
		if (!isset(self::$autoloader))	{
			self::$autoloader = new ModelAutoloader();
		}
		return self::$autoloader;
	}
	
	/**
	 * Get an entity from the backend.
	 * 
	 * Will ensure that only one instance of an entity will ever be
	 * floating around the system at any one time.
	 * 
	 * @param $entityType
	 * @param $key
	 * @return Entity
	 */
	public static function get($entityType, array $key = array())	{
		
		return self::getEntityCache()->getEntity($entityType, $key);
	}
	
	public static function getEntityCache()	{
		if (!isset(self::$entities))	{
			self::$entities = new EntityCache();
		}
		return self::$entities;
	}
	
	/**
	 * Checks whether the supplied class name is the name of an (probably undefined)
	 * entity class.
	 * 
	 * Can be used by autoloaders to check whether the class they are trying to autoload is actually
	 * a valid Entity or not.
	 * 
	 * @param $className
	 * @return bool
	 */
	public static function isClassNameAnEntity($className)	{
			//check defined entity names
			if (self::isAnEntityName($className))	{
				return true;
			}

			return false;

	}
	
	static public function getEntityNames()	{
		return self::$entityNames;
	}
	
	static public function setEntityNames(array $entityNames)	{
		self::$entityNames = $entityNames;
	}
	
	static public function addEntityName($entityName)	{
		self::$entityNames[] = $entityName;
	}
	
	static public function clearEntityNames()	{
		self::$entityNames = array();
	}
	
	static public function isAnEntityName($entityName)	{
		return in_array($entityName, self::getEntityNames());
	}
	
	/**
	 * Generates a list of valid entity names from the tables of the added
	 * databases.
	 */
	static public function generateValidEntityNamesFromDB()	{
		foreach(self::getDatabases() as $db)	{
			foreach($db->getTableNames() as $aTable)	{
				self::addEntityName($aTable);
			}
		}
	}
}
?>